﻿#include "CELLEpollServer.h"

#if __linux__

#include "CELLClient.h"
#include "CELLEpoll.hpp"

CELLEpollServer::CELLEpollServer()
{
	_ep.create(10240);
}

CELLEpollServer::~EasyEpollServer()
{
	Close();
}

bool CELLEpollServer::DoNetEvents()
{
	// 检测需要发送给客户端数据的客户端(这个可以根据情况而改变)
	for (auto iter : _clients)
	{
		if (iter.second->needWrite())
		{
			// 如果客户端有数据可发送，那么就检测可写
			_ep.ctl(EPOLL_CTL_MOD, iter.second, EPOLLOUT | EPOLLIN);
		}
		else
		{
			_ep.ctl(EPOLL_CTL_MOD, iter.second, EPOLLIN);
		}
	}

	int ret = _ep.wait(1);
	if (ret < 0)
	{
		CELLLog_pError("CELLEpollServer::DoNetEvents");
		return false;
	}
	else if (ret == 0)
	{
		return true;
	}
	
	auto events = _ep.events();
	for (int i = 0; i < ret; ++i)
	{
		CELLClient* pClient = (CELLClient*)events[i].data.ptr;
		if (pClient)
		{
			// 客户端可读
			if (events[i].events & EPOLLIN)
			{
				if (RecvData(pClient) == SOCKET_ERROR)
				{
					rmClient(pClient);
					continue;
				}
			}

			// 客户端可写
			if (events[i].events & EPOLLOUT)
			{
				if (pClient->SendDataReal() == SOCKET_ERROR)
				{
					rmClient(pClient);
				}
			}
		}
	}

	return true;
}

// remove Client
void CELLEpollServer::rmClient(CELLClient* pClient)
{
	auto iter = _clients.find(pClient->sockfd());
	if (iter != _clients.end())
	{
		_clients.erase(iter);
	}
	// 触发客户端离开事件(里面会删除客户端，所以放在后面)
	OnClientLeave(pClient);
}

// 本类中加入客户端加入事件
void CELLEpollServer::OnClientJoin(CELLClient* pClient)
{
	_ep.ctl(EPOLL_CTL_ADD, pClient, EPOLLIN);
}

#endif // #if __linux__
